/**
 * Copyright (c) 2009-2011, chunquedong(YangJiandong)
 * 
 * This file is part of ChunMap project
 * Licensed under the GNU LESSER GENERAL PUBLIC LICENSE(Version >=3)
 * 
 * History:
 *     2010-05-05  Jed Young  Creation
 */
package chunmap.raster.grid.data;

import java.io.File;
import java.io.FilenameFilter;

import chunmap.model.elem.Envelope;
import chunmap.raster.grid.Grid;
import chunmap.raster.grid.GridLayer;
import chunmap.raster.grid.TileImpl;

/**
 * @author chunquedong
 * 
 */
public class GridDataFactory {
	private String rootPath;
	private String parameters;
	private Envelope layerEnvelop;
	private String formatName = "jpeg";
	private int height;
	private int width;

	// private Envelop subEnvelop;
	private int buffer = 3;// 为了消除图片之间的缝隙

	public GridDataFactory(String rootPath, String parameters,
			Envelope layerEnvelop, int width, int height) {
		super();
		this.rootPath = rootPath;
		this.parameters = parameters;
		this.layerEnvelop = layerEnvelop;
		this.width = width;
		this.height = height;
	}

	public String getFormatName() {
		return formatName;
	}

	public void setFormatName(String formatName) {
		this.formatName = formatName;
	}

	public int getBuffer() {
		return buffer;
	}

	public void setBuffer(int buffer) {
		this.buffer = buffer;
	}

	// --------------------------------------------------------------------------
	public GridLayer createLayer() {
		GridLayer layer = new GridLayer();
		layer.setEnvelop(layerEnvelop);
		layer.setName(rootPath);

		File[] directoryList = getGridDirList();
		int num = directoryList.length;
		Grid[] grids = new Grid[num];

		// create GridDataSource
		FileImageData gridData = new FileImageData();
		gridData.setFormatName(formatName);
		gridData.setRootPath(rootPath);

		int i = 0;
		for (File dir : directoryList) {
			String path = dir.getPath();
			String dirName = dir.getName();

			double scale = getScale(dirName);
			Grid grid = new Grid();
			grid.setParameters(parameters);
			grid.setScale(scale);
			grid.setSubEnvelop(getEnvelop(0, 0, scale));

			setTile4Grid(grid, path);
			grid.setGridData(gridData);

			grids[i] = grid;
			i++;
		}
		layer.setGrids(grids);
		return layer;
	}

	private double getScale(String dir) {
		String[] s = dir.split("_");
		if (s.length == 2) {
			return Double.valueOf(s[1]);
		}
		return -1;
	}

	private File[] getGridDirList() {
		File file = new File(rootPath);
		File[] list = file.listFiles(new FilenameFilter() {
			@Override
			public boolean accept(File arg0, String name) {
				if (name.startsWith(parameters))
					return true;
				else
					return false;
			}
		});
		return list;
	}

	private void setTile4Grid(Grid grid, String path) {
		File[] tileList = getTileNameList(path);
		for (File tilePath : tileList) {
			String name = tilePath.getName();
			TileImpl tile = createTile(name, grid.getScale());

			grid.getTiles().add(tile);
			tile.setParent(grid);
		}
	}

	private TileImpl createTile(String name, double scale) {
		// create tile
		TileImpl tile = new TileImpl();

		// get x,y
		int x = -1, y = -1;
		String[] s = name.split("_");
		if (s.length == 2) {
			x = Integer.valueOf(s[0]);
			String[] ss = s[1].split("\\.");
			y = Integer.valueOf(ss[0]);
		}

		Envelope env = getEnvelop(x, y, scale);
		tile.setEnvelop(env);
		tile.setX(x);
		tile.setY(y);
		return tile;
	}

	private Envelope getEnvelop(int i, int j, double scale) {
		double w = width / scale;
		double h = height / scale;
		double ox = layerEnvelop.getMinX();
		double oy = layerEnvelop.getMinY();

		double dx = i * w + ox;
		double dy = j * h + oy;
		double dd = buffer / scale;

		Envelope envelop = new Envelope(dx, dy, dx + w + dd, dy + h + dd);
		return envelop;
	}

	private File[] getTileNameList(String path) {
		File file = new File(path);
		return file.listFiles();
	}
}